package com.qidian.buy.goods.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qidian.buy.dto.ItemMessageDTO;
import com.qidian.buy.goods.entity.Item;
import com.qidian.buy.goods.entity.ItemDesc;
import com.qidian.buy.goods.entity.ItemImage;
import com.qidian.buy.goods.mapper.ItemDescMapper;
import com.qidian.buy.goods.mapper.ItemImageMapper;
import com.qidian.buy.goods.mapper.ItemMapper;
import com.qidian.buy.goods.service.IItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qidian.buy.goods.vo.ItemVO;
import com.qidian.buy.util.Tools;
import com.qidian.buy.util.pojo.QdResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.*;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author 戴着假发的程序员
 * @since 2024-05-08
 */
@Service
@Transactional
public class ItemServiceImpl  implements IItemService {
    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private ItemImageMapper itemImageMapper;
    @Autowired
    private ItemDescMapper itemDescMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    public QdResult saveWrapper(ItemVO vo) {
        IItemService itemService = (IItemService) AopContext.currentProxy();
        QdResult result = itemService.save(vo);
        // 发送消息
        // 设置确认回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            // 如果确认失败，将信息保存到redis中的
            if(!ack){
                // 这里使用hash存储
                String key = "ITEM_MESSAGE_CONFIRM";
                String field = ItemMessageDTO.OP_INSERT + "_" + vo.getItemId();
                // 保存消息
                Map data = new HashMap();
                data.put("op",ItemMessageDTO.OP_INSERT);
                data.put("itemId",vo.getItemId());
                data.put("cause",cause);
                // 保存数据到redis中
                stringRedisTemplate.opsForHash().put(key,field, Tools.object2json(data));
            }
        });
        // 失败回调
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            // 这里使用hash存储
            String key = "ITEM_MESSAGE_FAL";
            String field = ItemMessageDTO.OP_INSERT + "_" + vo.getItemId();
            // 保存消息
            Map data = new HashMap();
            data.put("op",ItemMessageDTO.OP_INSERT);
            data.put("message",message);
            data.put("replyCode",replyCode);
            data.put("replyText",replyText);
            data.put("exchange",exchange);
            data.put("routingKey",routingKey);
            data.put("itemId",vo.getItemId());
            // 保存数据到redis中
            stringRedisTemplate.opsForHash().put(key,field, Tools.object2json(data));
        });
        // 发送消息
        rabbitTemplate.convertAndSend("item-direct-exchange","item",Tools.object2json(ItemMessageDTO.insert(vo.getItemId())));
        return result;
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public QdResult save(ItemVO vo) {
        // 保存商品信息
        int insert = itemMapper.insert(vo);
        if(insert == 1) {
            // 保存商品成功之后，就有商品编号了。
            Long itemId = vo.getItemId();
            // 给图片设置商品编号
            List<String> imageUrls = vo.getImageUrl();
            // 保存所有的图片
            for (String imageUrl : imageUrls) {
                // 保存图片
                ItemImage itemImage = new ItemImage();
                itemImage.setItemId(itemId);
                itemImage.setImageUrl(imageUrl);
                itemImageMapper.insert(itemImage);
            }
            // 保存商品详情信息
            ItemDesc itemDesc = new ItemDesc();
            itemDesc.setItemId(itemId);
            itemDesc.setItemDesc(vo.getItemDesc());
            itemDescMapper.insert(itemDesc);
            // 发送消息
            return QdResult.success();
        }
        return  QdResult.error();
    }

    @Override
    public QdResult list(Item item, int page, int limit) {
        IPage<Item> iPage = new Page<>(page,limit);
        QueryWrapper<Item> wrapper = new QueryWrapper<>();
        // 查询条件
        if(item != null){
            wrapper.like(!StringUtils.isBlank(item.getItemTitle()),"item_title",item.getItemTitle());
            wrapper.eq(item.getCatId() != null && item.getCatId() != 0,"cat_id",item.getCatId());
            wrapper.eq(item.getStatus() != null && item.getStatus() != 0,"status",item.getStatus());
            wrapper.between(item.getCreateStart() != null && item.getCreateEnd() != null,"created",item.getCreateStart(),item.getCreateEnd());
        }
        IPage<Item> itemIPage = itemMapper.selectPage(iPage, wrapper);
        // 查询商品完成之后，遍历所有的商品信息逐个查询商品图片。
        itemIPage.getRecords().forEach(buyItem->{
            QueryWrapper<ItemImage> imageWrapper = new QueryWrapper<>();
            imageWrapper.eq("item_id",buyItem.getItemId());
            List<ItemImage> itemImages = itemImageMapper.selectList(imageWrapper);
            List<String> images = new ArrayList<>();
            itemImages.forEach(image->{
                images.add(image.getImageUrl());
            });
            buyItem.setImages(images);
        });
        return QdResult.success(itemIPage);
    }

    @Override
    public QdResult addItemAndSpeRelation(Long itemId, List<Long> speId) {
        // 删除之前的关系
        itemMapper.deleteItemAndSpeRelationByItemId(itemId);
        // 增加新的关系
        itemMapper.addItemAndSpeRelation(itemId,speId);
        return QdResult.success();
    }

    @Override
    public QdResult getSpeIdByItemId(Long itemId) {
        return QdResult.success(itemMapper.getSpeIdByItemId(itemId));
    }

    @Override
    public QdResult getByItemId(Long itemId) {
        Item item = itemMapper.selectById(itemId);
        QueryWrapper<ItemImage> imageWrapper = new QueryWrapper<>();
        imageWrapper.eq("item_id",item.getItemId());
        List<ItemImage> itemImages = itemImageMapper.selectList(imageWrapper);
        List<String> images = new ArrayList<>();
        itemImages.forEach(image->{
            images.add(image.getImageUrl());
        });
        item.setImages(images);
        return QdResult.success(item);
    }

    @Override
    public QdResult detail(Long itemId) {
        return QdResult.success(itemMapper.getByItemId(itemId));
    }


}
